<?php
ini_set('display_errors', true);
/**
 * Expression Engine Exporter
 * @author Aaron Brazell <aaron@technosailor.com>
 * @version 1.0-alpha
 *
 * This class will export Expression Engine as a
 *  WordPress eXtended RSS (WXR) file.
 *  It can then be imported using the WordPress
 *  import utility
 *
 * This code is licensed under GPLv2 
 *  http://www.fsf.org/licensing/licenses/info/GPLv2.html
 *
 * Example Usage:
 *  $e = new ExpressionEngineExport('exp_','my_weblog','America/New_York');
 */

// This will change. However, it assumes that this file is in the root directory of a working WordPress install
include('wp-config.php');
include('wp-includes/wp-db.php');

//TODO: Author for feed
class ExpressionEngineExport {
	
	var $ee_prefix;
	var $ee_blogname;
	var $ee_timezone;
	
	function ExpressionEngineExport( $prefix, $blogname, $timezone)
	{		
		return $this->__construct($prefix, $blogname, $timezone);
	}
	
	function __construct($prefix, $blogname, $timezone)
	{
		$this->ee_prefix = $prefix;
		$this->ee_blogname = $blogname;
		$this->ee_timezone = $timezone;
		
		$this->_set_timezone();
		$this->execute();
	}
	
	function __destruct()
	{
		return true;
	}
	
	function execute()
	{
		$main_settings = $this->_get_blog_settings();
		$entries = $this->_get_entries( $main_settings->weblog_id );
		$categories = $this->_get_categories( $entries );
		
		$this->_wxr_export( $main_settings, $entries, $categories );
	}
	
	function _get_blog_settings()
	{
		global $wpdb;
		$blog = $wpdb->get_row('select weblog_id, blog_title, blog_description, blog_url from ' . $this->ee_prefix . 'weblogs where blog_name = "' . $this->ee_blogname . '"');
		$blog->author = $wpdb->get_var('select username from ' . $this->ee_prefix . 'members where group_id = 1 limit 1');
		return $blog;
	}
	
	function _get_author( $authorid )
	{
		global $wpdb;
		return $wpdb->get_row('select * from ' . $this->ee_prefix . 'members where member_id = ' . $authorid);
	}
	
	function _get_entries( $blog_id )
	{
		global $wpdb;
		$ids = $wpdb->get_col('select entry_id from ' . $this->ee_prefix . 'weblog_data where weblog_id="' . $blog_id . '"');
		return $wpdb->get_results('select * from ' . $this->ee_prefix . 'weblog_titles left join ' . $this->ee_prefix . 'weblog_data on (' . $this->ee_prefix . 'weblog_titles.entry_id=' . $this->ee_prefix . 'weblog_data.entry_id) group by ' . $this->ee_prefix . 'weblog_titles.entry_id');
	}
	
	function _get_categories( $entries )
	{
		global $wpdb;
		
		$entry_ids = array();
		foreach( $entries as $entry )
			$entry_ids[] = $entry->entry_id;
		$cat_ids = $wpdb->get_col('select distinct(cat_id) from ' . $this->ee_prefix . 'category_posts where entry_id in (' . implode(',', $entry_ids) . ')');
		if( !empty( $cat_ids ) )
		{
			$cat_ids = implode(',', $cat_ids);
			return $wpdb->get_results('select cat_id, parent_id, cat_name, cat_description from ' . $this->ee_prefix . 'categories where cat_id in (' . $cat_ids . ')');
		}
		else
			return false;
	}
	
	function _get_cats_for_post( $postid )
	{
		global $wpdb;
		$cat_id_str = $wpdb->get_col('select cat_id from ' . $this->ee_prefix . 'category_posts where entry_id = ' . $postid);
		if( !empty( $cat_id_str ) )
		{
			$cat_ids = implode(',', $cat_id_str);
			return $wpdb->get_results('select cat_id, parent_id, cat_name, cat_description from ' . $this->ee_prefix . 'categories where cat_id in (' . $cat_ids . ')');
		}
		else
			return false;
	}
	
	function _set_comment_open( $curstatus )
	{
		if($curstatus == 'y')
			$newstatus = 'open';
		else
			$newstatus = 'closed';
		return $newstatus;
	}
	
	function _set_post_status( $curstatus )
	{
		if( $curstatus = 'open')
			$newstatus = 'publish';
		else
			$newstatus = 'draft';
		return $newstatus;
	}
	
	function _set_comment_status( $curstatus )
	{
		if( $curstatus == 'o' )
			$newstatus = '1';
		else
			$newstatus = 'spam';
		return $newstatus;
	}
	
	function _set_comment_type( $comment )
	{
		if( Utility::string_present('\[\.\.\.]', $comment) )
			$newtype = 'pingback';
		else
			$newtype = '';
		return $newtype;
	}
	
	function _set_timezone()
	{
	date_default_timezone_set( $this->ee_timezone );
	}
		
	function _format_entry_xml( $entry, $categories, $siteurl )
	{
		// TODO: We are going to use field_id_2 but this appears to vary from blog to blog so we need to grok the right field before using
		//echo'<pre>';echo $this->_get_author( $entry->author_id )->username;echo'</pre>';exit;
		$xml = '<item>
			<title>' . $entry->title . '</title>
			<link>' . $siteurl . $entry->url_title .'</link>
			<pubDate>' . date('D, j M Y H:i:s O', $entry->entry_date) . '</pubDate>
			<dc:creator>' . $this->_get_author( $entry->author_id )->username . '<dc:creator>';
			
			if( $categories = $this->_get_cats_for_post( $entry->entry_id ) )
			{
				foreach( $categories as $category)
				{
				$xml .= '<category><![CDATA[' . $category->cat_name . ']]></category>
			<category domain="category" nicename="' . Utility::sanitize( $category->cat_name ) . '"><![CDATA[' . $category->cat_name . ']]></category>' . "\n";
				}
			}
		$xml .= '<guid isPermalink="false">' . $siteurl . $entry->url_title .'</guid>
			<description></description>
			<content:encoded><![CDATA[' . $entry->field_id_2 . ']]></content:encoded>
			<wp:post_date>' . date('Y-m-d H:i:s', $entry->entry_date) . '</wp:post_date>
			<wp:post_date_gmt>' . gmdate( 'Y-m-d H:i:s', $entry->entry_date ) . '</wp:post_date_gmt>
			<wp:comment_status>' . $this->_set_comment_open( $entry->allow_comments ) . '</wp:comment_status>
			<wp:ping_status>' . $this->_set_comment_open( $entry->allow_trackbacks ) . '</wp:ping_status>
			<wp:post_name>' . $entry->url_title . '</wp:post_name>
			<wp:status>' . $this->_set_post_status( $entry->status ) . '</wp:status>
			<wp:post_type>post</wp:post_type>
			' . $this->_format_comment_xml( $entry->entry_id ) . '
		</item>' . "\n";
		return $xml;
	}
	
	function _format_comment_xml( $entry_id )
	{
		global $wpdb;
		$xml = '';
		foreach( $wpdb->get_results('select * from ' . $this->ee_prefix . 'comments where entry_id = ' . $entry_id ) as $comment)
		{
			$xml .= '<wp:comment>
				<wp:comment_id>' . $comment->comment_id . '</wp:comment_id>
				<wp:comment_author>' . $comment->name . '</wp:comment_author>
				<wp:comment_author_email>' . $comment->email . '</wp:comment_author_email>
				<wp:comment_author_url>' . $comment->url . '</wp:comment_author_url>
				<wp:comment_author_IP>' . $comment->ip_address . '</wp:comment_author_IP>
				<wp:comment_date>' . date('Y-m-d H:i:s', $comment->comment_date) . '</wp:comment_date>
				<wp:comment_date_gmt>' . gmdate( 'Y-m-d H:i:s', $comment->comment_date ) . '</wp:comment_date_gmt>
				<wp:comment_content>' . $comment->comment . '</wp:comment_content>
				<wp:comment_approved>' . $this->_set_comment_status( $comment->status ) . '</wp:comment_approved>
				<wp:comment_type>' . $this->_set_comment_type( $comment->comment ) . '</wp:comment_type>
				<wp:comment_parent>0</wp:comment_parent>
			</wp:comment>' . "\n";
		}
		return $xml;
	}
	
	function _format_category_xml( $categories )
	{
		$xml .= '<wp:category>' . "\n";
		foreach( $categories as $category )
		{
			$xml .= '<wp:category_nicename>' . Utility::sanitize( $category->cat_name ) . '</wp:category_nicename><wp:category_parent></wp:category_parent><wp:cat_name><![CDATA[' . $category->cat_name . ']]></wp:cat_name></wp:category>' . "\n";
		}
		$xml .= '</wp:category>' . "\n";
		return $xml;
	}
	
	function _wxr_export( $blog_settings, $entries, $categories )
	{
		$xml = '<?xml version="1.0" encoding="UTF-8"?>
		<rss version="2.0"
			xmlns:content="http://purl.org/rss/1.0/modules/content/"
			xmlns:wfw="http://wellformedweb.org/CommentAPI/"
			xmlns:dc="http://purl.org/dc/elements/1.1/"
			xmlns:wp="http://wordpress.org/export/1.0/"
		>
		<channel>
			<title>' . $blog_settings->blog_title . '</title>
			<link>' . $blog_settings->blog_url . '</link>
			<description>' . $blog_settings->blog_description . '</description>
			<pubDate>' . date('D, j M Y H:i:s O') . '</pubDate>
			<generator>http://www.b5media.com</generator>
			<language>en</language>
			<wp:wxr_version>1.0b5alt</wp:wxr_version>
			<wp:base_site_url>http://wordpress.com/</wp:base_site_url>
			<wp:base_blog_url>' . $blog_settings->blog_url . '</wp:base_blog_url>
			<dc:creator>' . $blog_settings->author . '</dc:creator>
			' . $this->_format_category_xml( $categories ) . '
		</channel>' . "\n";
		foreach($entries as $item)
			$xml .= $this->_format_entry_xml( $item, $categories, $blog_settings->blog_url );
		$xml .= '</rss>';
		
			$filename = 'expression-engine-wxr.' . date('Y-m-d') . '.xml';
			header('Content-Description: File Transfer');
			header("Content-Disposition: attachment; filename=$filename");
			header('Content-type: text/xml; charset=UTF-8');
			//echo'<?xml version="1.0" encoding="UTF-8"?' . ">\n";
			
			echo $xml;
	}
	
}

class Utility {
	
	function sanitize( $str ) {
		$str = strip_tags($str);
		// Preserve escaped octets.
		$str = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $str);
		// Remove percent signs that are not part of an octet.
		$str = str_replace('%', '', $str);
		// Restore octets.
		$str = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $str);

		$str = remove_accents($str);
		if (seems_utf8($str)) {
			if (function_exists('mb_strtolower')) {
				$str = mb_strtolower($str, 'UTF-8');
			}
			$str = utf8_uri_encode($str, 200);
		}

		$str = strtolower($str);
		$str = preg_replace('/&.+?;/', '', $str); // kill entities
		$str = preg_replace('/[^%a-z0-9 _-]/', '', $str);
		$str = preg_replace('/\s+/', '-', $str);
		$str = preg_replace('|-+|', '-', $str);
		$str = trim($str, '-');

		return $str;
	}
	
	function write_log( $file, $data )
	{
		if( file_put_contents($file, $data) )
			return true;
		else
			return false;
	}
	
	function string_present( $needle, $haystack )
	{
		$pattern = "#$needle#";
		if( preg_match($pattern, $haystack) )
			return true;
		else
			return false;
	}
}
?>